-- 2022-8-18

---[[ 20.0

    -- 通常 Lua语言中的每种类型的值都有一套可预见的操作集合 例如 我们可以将数字相加 可以连接字符串 还可以在表中插入键值对等
    -- 但是 我们无法将两个表相加 无法对函数作比较 也无法调用一个字符串 除非使用元表

    -- 元表可以修改一个值在面对一个未知操作时的行为 例如 假设a和b都是表 那么可以通过元表定义Lua语言如何计算表达式a + b
    -- 当Lua语言试图将两个表相加时 它会先检查两者之一是否有元表(metatable)且该元表中是否有__add字段
    -- 如果Lua语言找到了该字段 就调用该字段对应的值 即所谓的元方法(metamethod)(是一个函数) 在本例中就是用于计算表的和的函数

    -- 可以认为 元表是面向对象领域中的受限制类 像类一样 元表定义的是实例的行为
    -- 不过 由于元表只能给出预先定义的操作合集的行为 所以元表比类更受限 同时 元表也不支持继承
    -- 不过尽管如此 我们还是会在第21章中看到如何基于元表构建一个相对完整的类系统

    -- Lua语言中的每一个值都可以有元表 每一个表和用户数据类型都具有各自独立的元表 而其他类型的值则共享对应类型所属的同一个元表 Lua语言在创建新表时不带元表:
    local t = {}
    print(getmetatable(t)) --> nil
    -- 可以使用函数setmetatable来设置或修改任意表的元表:
    local t1 = {}
    setmetatable(t,t1)
    print(getmetatable(t) == t1) --> true

    -- 一个表可以成为任意值的元表 一组相关的表也可以共享一个描述了它们共同行为的通用元表 一个表还可以成为它自己的元表 用于描述其自身特有的行为 总之 任何配置都是合法的
--]]